//
//  ZRScanManager.m
//  简书:https://www.jianshu.com/u/043e94ca450f
//
//  Created by 黄涛 on 2018/8/23.
//  Copyright © 2018年 黄涛(ZR:zero). All rights reserved.
//  扫一扫

#import "ZRScanManager.h"

@interface ZRScanManager () <AVCaptureMetadataOutputObjectsDelegate,AVCaptureVideoDataOutputSampleBufferDelegate>

@end

static ZRScanManager * _manager;

static char * const queue_videoDataOutput = "VideoDataOutput";

@implementation ZRScanManager

/** 初始化 */
+ (instancetype)sharedManager{
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        _manager = [[ZRScanManager alloc] init];
        _manager.brightnessThreshold = -0.2;
        
    });
    
    return _manager;
}


#pragma mark - ----------------------- 其他方法 -----------------------

/** 打开/关闭 手电筒 */
+ (void)turnTorchOn:(BOOL)isOn{

    if (![_manager.device hasTorch]){ NSLog(@"没有手电筒");return;}
    [_manager.device lockForConfiguration:nil];
    [_manager.device setTorchMode:isOn ? AVCaptureTorchModeOn : AVCaptureTorchModeOff];
}

#pragma mark - ----------------------- 代理方法 -----------------------
#pragma mark - AVCaptureMetadataOutputObjects Delegate
- (void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
    
    [_manager.session stopRunning];
    
     NSString * result = [metadataObjects.firstObject stringValue];
    
    !_scanSuccess ? : _manager.scanSuccess(result);
    
    //扫描成功提示音
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    AudioServicesPlaySystemSound(1109);
}

#pragma mark - AVCaptureVideoDataOutputSampleBuffer Delegate
- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{
    
    //获取元数据
    CFDictionaryRef metaDataDicRef = CMCopyDictionaryOfAttachments(NULL, sampleBuffer, kCMAttachmentMode_ShouldPropagate);
    NSDictionary * meadDataDic = [[NSDictionary alloc] initWithDictionary:(__bridge NSDictionary * _Nonnull)(metaDataDicRef)];
    CFRelease(metaDataDicRef);
    
    //拍摄信息
    NSDictionary * exifDic = [meadDataDic objectForKey:(NSString *)kCGImagePropertyExifDictionary];
    //获取亮度值
    float brightnessValue = [[exifDic objectForKey:(NSString *)kCGImagePropertyExifBrightnessValue] floatValue];
    
    !_deviceBrightnessValueBlock ? : self.deviceBrightnessValueBlock(brightnessValue);

}


#pragma mark - ----------------------- 活动监听 -----------------------
#pragma mark - ---------------------- set & get ----------------------
/** 摄像设备 */
- (AVCaptureDevice *)device{
    if (!_device) {
        _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    }
    return _device;
}

/** 输入流 */
- (AVCaptureDeviceInput *)input{
    if (!_input) {
        NSError * error;
        _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:&error];
        if (error) NSLog(@"输出流 报错:%@",error);
    }
    return _input;
}

/** 输出流:元数据 */
- (AVCaptureMetadataOutput *)metaOutput{
    if (!_metaOutput) {
        _metaOutput = [[AVCaptureMetadataOutput alloc] init];
        [_metaOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    }
    return _metaOutput;
}


- (AVCaptureVideoDataOutput *)videoOutput{
    if (!_videoOutput) {
        
        _videoOutput = [[AVCaptureVideoDataOutput alloc] init];
        _videoOutput.videoSettings = [NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInteger:kCVPixelFormatType_32BGRA] forKey:(NSString *)kCVPixelBufferPixelFormatTypeKey];
        [_videoOutput setAlwaysDiscardsLateVideoFrames:YES];
        dispatch_queue_t queue = dispatch_queue_create(queue_videoDataOutput, DISPATCH_QUEUE_SERIAL);
        [_videoOutput setSampleBufferDelegate:self queue:queue];
    }
    return _videoOutput;
}



/** 连接对象 */
- (AVCaptureSession *)session{
    if (!_session) {
        _session = [[AVCaptureSession alloc] init];
        [_session setSessionPreset:AVCaptureSessionPreset1280x720];
        
        if ([_session canAddInput:self.input]) {
            [_session addInput:self.input];
        }
        
        if ([_session canAddOutput:self.metaOutput]) {
            [_session addOutput:self.metaOutput];
            _metaOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
        }
        
        if ([_session canAddOutput:self.videoOutput]) {
            [_session addOutput:self.videoOutput];
        }
        
    }
    return _session;
}

/** 视频层 */
- (AVCaptureVideoPreviewLayer *)videoLayer{
    if (!_videoLayer) {
        _videoLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
        _videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    
        AVCaptureConnection * previewLayerConnection = _videoLayer.connection;
        //2、判断并修正
        if ([previewLayerConnection isVideoOrientationSupported])
        {
            [previewLayerConnection setVideoOrientation:(AVCaptureVideoOrientation)[UIApplication sharedApplication].statusBarOrientation];
        }
    }
    return _videoLayer;
}


@end
